package com.topvision.gsj.launcher.util;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.util.Log;

public class EventUtil {

	public static final String EPSON_GLASSES = "moverio";//TODO
	public static final String VUZIX_GLASSES = "Vuzix";

	/**
	 * 执行shell命令
	 * 
	 * @param cmd
	 */
	public static void execShellCmd(String cmd) {

		try {
			// 申请获取root权限，这一步很重要，不然会没有作用
			Process process = Runtime.getRuntime().exec("su");
			// 获取输出流
			OutputStream outputStream = process.getOutputStream();
			DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
			dataOutputStream.writeBytes(cmd);
			dataOutputStream.flush();
			dataOutputStream.close();
			outputStream.close();
		} catch (Throwable t) {
			t.printStackTrace();
		}
	}
	
	/**
	 * 执行shell命令
	 * 
	 * @param cmd
	 */
	public static String execShellCmd(String cmd, boolean readOutput) {

		try {
			// 申请获取root权限，这一步很重要，不然会没有作用
			Process process = Runtime.getRuntime().exec("su");
			// 获取输出流
			OutputStream outputStream = process.getOutputStream();
			InputStream inputStream = process.getInputStream();
			
			DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
			dataOutputStream.writeBytes(cmd);
			dataOutputStream.flush();
			dataOutputStream.close();
			outputStream.close();

			StringBuilder sb = new StringBuilder();
			BufferedReader ir = new BufferedReader(new InputStreamReader(inputStream)); 
			String line = null;
			while((line=ir.readLine())!=null){
				sb.append(line);
			}
			System.out.println(sb.toString());
			ir.close();
			inputStream.close();
			return sb.toString();
		} catch (Throwable t) {
			t.printStackTrace();
		}
		return null;
	}
	
	private static Random ran = new Random();
	
	/**
	 * 将click命令封装起来
	 * @param x
	 * @param y
	 */
	public static void simulateClick(int eventNum, int x, int y){
		int uniqueId = ran.nextInt(65535);
		execShellCmd("sendevent /dev/input/event"+eventNum+" 3 57 "+uniqueId);//事件开始,触点区分的唯一id
		execShellCmd("sendevent /dev/input/event"+eventNum+" 3 48 100");//点击开始 (接触椭圆的长轴)
		execShellCmd("sendevent /dev/input/event"+eventNum+" 3 50 20");//(接近椭圆的长轴)
		execShellCmd("sendevent /dev/input/event"+eventNum+" 3 58 20");//触摸压力值
		execShellCmd("sendevent /dev/input/event"+eventNum+" 3 53 "+x);//x坐标
		execShellCmd("sendevent /dev/input/event"+eventNum+" 3 54 "+y);//y坐标
		execShellCmd("sendevent /dev/input/event"+eventNum+" 0 0 0");//点击结束
		execShellCmd("sendevent /dev/input/event"+eventNum+" 3 57 4294967295");//事件结束
		execShellCmd("sendevent /dev/input/event"+eventNum+" 0 0 0");//事件同步
	}
	
	
	public static void simulateClickSimulator(int eventNum, long x, long y){
		execShellCmd("sendevent /dev/input/event"+eventNum+" 3 0 "+x);//事件开始,触点区分的唯一id
		execShellCmd("sendevent /dev/input/event"+eventNum+" 3 1 "+y);//点击开始 (接触椭圆的长轴)
		execShellCmd("sendevent /dev/input/event"+eventNum+" 1 330 1");//y坐标
		execShellCmd("sendevent /dev/input/event"+eventNum+" 0 0 0");//点击结束
		execShellCmd("sendevent /dev/input/event"+eventNum+" 1 330 0");//事件结束
		execShellCmd("sendevent /dev/input/event"+eventNum+" 0 0 0");//事件同步
	}

	/**
	 * 将click命令封装起来
	 * @param x
	 * @param y
	 */
	public static void simulateSimulatorBack(String brand){
		if(EPSON_GLASSES.equals(brand)){
			execShellCmd("sendevent /dev/input/event0 1 158 1", true);//y坐标
			execShellCmd("sendevent /dev/input/event0 0 0 0", true);//点击结束
			execShellCmd("sendevent /dev/input/event0 1 158 0", true);//事件结束
			execShellCmd("sendevent /dev/input/event0 0 0 0", true);//事件同步
		}else{
			execShellCmd("sendevent /dev/input/event0 1 1 1", true);//y坐标
			execShellCmd("sendevent /dev/input/event0 0 0 0", true);//点击结束
			execShellCmd("sendevent /dev/input/event0 1 1 0", true);//事件结束
			execShellCmd("sendevent /dev/input/event0 0 0 0", true);//事件同步
		}
		
	}
	
	/**
	 * 将click命令封装起来
	 * @param x
	 * @param y
	 */
	public static void simulateBack(){
		execShellCmd("input keyevent 4");
	}
	
	/**
	 * 将click命令封装起来
	 * @param x
	 * @param y
	 */
	public static void simulateHome(){
		execShellCmd("input keyevent 3");
	}
	
	/**
	 * 获取设备中的长度和宽度
	 * @return
	 */
	public static int[] getEventWidthHeight(){
		String result = execShellCmd("getevent -p | grep -e \"0035\" -e \"0036\"", true);
//        0035  : value 0, min 0, max 1620, fuzz 0, flat 0, resolution 0                
//		  0036  : value 0, min 0, max 2880, fuzz 0, flat 0, resolution 0
		
		return extractWidthHeight(result);
	}
	

	
	/**
	 * M100眼镜中模拟点击不能直接传入坐标，而是以中点为0点，向下、向上变化
	 * @param x
	 * @param y
	 * @param screenWidth
	 * @param screenHeight
	 * @return
	 */
	public static long[] getTransferedPoint(float x, float y, int screenWidth, int screenHeight){
		float midScreenWidth = (float) (screenWidth/2.0);
		float midScreenHeight = (float) (screenHeight/2.0);
		long[] poingValue = new long[2];
		if(x==midScreenWidth){
			poingValue[0] = 0;
		}else{
			float gap = x - midScreenWidth;
			double ratio = Math.abs(gap/midScreenWidth);
			int value = (int)(ratio*2048);
			if(gap>0){//在中点的右边
				poingValue[0] = value;
			}else{//在中点的左边
				poingValue[0] = Long.parseLong("FFFFFFFF", 16)-value;
			}
		}
		if(y==midScreenHeight){
			poingValue[1] = 0;
		}else{
			float gap = y - midScreenHeight;
			double ratio = Math.abs(gap/midScreenHeight);
			int value = (int)(ratio*2048);
			if(gap>0){//在中点的下边
				poingValue[1] = value;
			}else{//在中点的上边
				poingValue[1] = Long.parseLong("FFFFFFFF", 16)-value;
			}
		}
		return poingValue;
	}
	
	
	
	public static void main(String[] args){
//		long[] pointValue = getTransferedPoint(247, 137, 432, 244);
//		System.out.println(pointValue[0]+" "+Long.toHexString(pointValue[0]));
//		System.out.println(pointValue[1]+" "+Long.toHexString(pointValue[1]));
		
		String resultStr = "add device 11: /dev/input/event7  add device 12: /dev/input/event6  add device 13: /dev/input/event5 add device 15: /dev/input/event2";
		int num = extractTouchEventNumEmulator(resultStr);
		System.out.println(num);
	}
	
	
	/**
	 * 解析出设备中长度和宽度
	 * @param resultStr
	 * @return
	 */
	private static int[] extractWidthHeight(String resultStr){
		if(resultStr==null||resultStr.equals("")){
			return null;
		}
		Pattern patt = Pattern.compile("0035 .*?max (\\d*).*?0036 .*?max (\\d*).*?");
		Matcher matt = patt.matcher(resultStr);
		if(matt.find()){
			return new int[]{Integer.parseInt(matt.group(1)), Integer.parseInt(matt.group(2))};
		}
		return null;
	}
	
	
	/**
	 * 获取touch的设备编号，模拟器一般是0， 我的htc手机是5, M100是7
	 * @return
	 */
	public static int getTouchEventNum(){
		String result = execShellCmd("getevent -p", true);
		return extractTouchEventNum(result);
	}
	
	/**
	 * 获取touch的设备编号，模拟器一般是0， 我的htc手机是5, M100是7, Epson是15
	 * @return
	 */
	public static int getTouchEventNum(String brand){
		String result = execShellCmd("getevent -p", true);
		if(VUZIX_GLASSES.contains(brand)||EPSON_GLASSES.contains(brand)){
			return extractTouchEventNumEmulator(result);
		}else{
			return extractTouchEventNum(result);
		}
	}
	
	/**
	 * 解析出设备中输入的event的编号
	 * @param resultStr
	 * @return
	 */
	private static int extractTouchEventNum(String resultStr){
		if(resultStr==null||resultStr.equals("")){
			return 0;
		}
		Pattern patt = Pattern.compile("add device \\d*?: /dev/input/event(\\d*)[\\s]*?name:[\\s]*?\"[~\\S]*?-touchscreen\".*?");
		Matcher matt = patt.matcher(resultStr);
		if(matt.find()){
			return Integer.parseInt(matt.group(1));
		}
		return 0;
//		return 7;//Vuzix
//		return 15;//EPSON
	}
	
	
	/**
	 * 解析出设备中输入的event的编号(用vnc虚拟出的设备编号)
	 * @param resultStr
	 * @return
	 */
	private static int extractTouchEventNumEmulator(String resultStr){
		if(resultStr==null||resultStr.equals("")){
			return 0;
		}
		//如果有用到vnc则会虚拟出一个设备，获取此设备的eventnum
		Pattern patt = Pattern.compile("add device \\d*?: /dev/input/event(\\d*)[\\s]*?name:[\\s]*?\"qwerty\".*?");
		Matcher matt = patt.matcher(resultStr);
		if(matt.find()){
			return Integer.parseInt(matt.group(1));
		}

		patt = Pattern.compile("add device (\\d*?): /dev/input/event(\\d*)[\\s]*?");
		matt = patt.matcher(resultStr);
		int returnNum = -1;
		while(matt.find()){
			int num = Integer.parseInt(matt.group(1));
			if(num>returnNum){
				returnNum = num;
			}
		}
		return returnNum>0?returnNum:15;//EPSON
//		return 7;//Vuzix
	}
	
}
